-
Notifications
You must be signed in to change notification settings - Fork 6
Migrate www to Fumadocs #219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…orrect behavior during user loading.
…ion, and core application pages.
…and downgrade `@esbuild` packages.
…th Bedstack branding, and initialize documentation structure.
…e associated assets, and add `clsx` dependency.
…tHub Discussions.
…ayout to notebook style.
…apsible sidebar, and container styling, and enable Tailwind CSS parsing in Biome.
… shell command formatting in getting started guides.
…out props and footer styling; chore: remove unused CSS.
…__dirname` polyfill.
…y using `path.resolve` instead of a custom `__dirname` utility.
…lysiaJS, and Drizzle on the homepage.
…ce a bed illustration, and update the GitHub icon.
…ono fonts, and refine global navigation styles.
…ing, and improve responsive logo sizing.
…nd refining flex properties for alignment.
…ude subnav div, and update sidebar positioning and height.
…navigation styling.
…, and apply to docs layout
…nt, and refine the Bedstack acronym definition.
…g Started' to 'RealWorld' and refreshing homepage content.
…Started' card title.
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
WalkthroughMigrates the docs site from VitePress to a Next.js + Fumadocs MDX app (apps/www), preserves the VitePress site under apps/www-legacy, removes Discord contact links across templates/docs, updates CI/build targets and local tooling, and adds many new UI, route, and content files for the Fumadocs site. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant NextRoute as Next /docs/[[...slug]]
participant Source as fumadocs source
participant MDX as MDX renderer
Client->>NextRoute: GET /docs/:slug
NextRoute->>Source: source.getPage(slug)
alt page found
Source-->>NextRoute: page (title, body, meta, processed)
NextRoute->>MDX: render page.body with getMDXComponents
MDX-->>NextRoute: rendered HTML/JSX
NextRoute-->>Client: 200 HTML (page + metadata)
else not found
NextRoute-->>Client: 404
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ead of `apps/www`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 16
🤖 Fix all issues with AI agents
In @.github/workflows/deploy-www.yml:
- Around line 51-58: The workflow's docs:build step runs the npm script that
executes "turbo run build --filter=www" (building Next.js under the www package)
but the Upload artifact step points to "apps/www-legacy/.vitepress/dist"
(VitePress) causing an empty artifact; either change the build invocation to
target the legacy site (run turbo run build --filter=www-legacy / update
docs:build to build www-legacy) or change the upload path to the Next.js output
(apps/www/.next) so the artifact matches the built package; update the
.github/workflows/deploy-www.yml steps accordingly, keeping the names "Build
with VitePress"/"Upload artifact" consistent with the chosen target.
In `@apps/www-legacy/.vitepress/config.ts`:
- Line 37: The navigation entry with text 'Getting Started' currently uses the
link '/realworld' which points to a non-existent page; update that navigation
object (the { text: 'Getting Started', link: '/realworld' } entry) to use the
existing page path '/getting-started' or alternatively add a new realworld.md
page to the site so the '/realworld' link resolves.
In `@apps/www-legacy/package.json`:
- Around line 6-10: The package.json declares a "clean" script that calls rimraf
but rimraf is not listed in this package's devDependencies; add a
devDependencies entry for "rimraf" with version "^6.1.2" in apps/www-legacy's
package.json (alongside existing devDependencies) so the "clean" script's
dependency is explicit and versioned.
In `@apps/www/content/docs/realworld.mdx`:
- Line 12: The markdown link text "[Bun](https://bun.com/)" is pointing to the
wrong domain; update the URL to the official site by replacing
"https://bun.com/" with "https://bun.sh/" in the line that reads
'[Bun](https://bun.com/) version 1.0.6 or higher.' so the link correctly targets
Bun's official website.
- Around line 21-43: The numbered list's fenced code blocks are inconsistently
indented (step 1 has two leading spaces while steps 2–4 have none), which can
break MDX list nesting; update each fenced code block under the steps ("1.
**Ensure...", "2. **Ensure Docker...", "3. **Migrate...", "4. **Run the app") so
the opening and closing ```sh and their contents are indented the same amount
(use 3 or 4 spaces consistently, e.g., indent the ```sh, commands, and closing
``` by three spaces) so all code blocks remain correctly nested within their
list items.
In `@apps/www/README.md`:
- Line 1: Replace the placeholder title line "# ." in the README with a
meaningful project title; edit the top-level heading (the line containing "# .")
to something descriptive such as "# Bedstack Docs" or "# www" so the README has
a proper title and clearly identifies the repository.
- Line 16: Replace the bare URL in the README line "Open http://localhost:3000
with your browser to see the result." with a proper markdown link (e.g.,
[http://localhost:3000](http://localhost:3000)) or angle-bracket form
(<http://localhost:3000>) so the URL is rendered/clickable; update that single
sentence accordingly.
- Around line 22-23: Update the README entries that reference lib/source.ts and
lib/layout.shared.tsx to use the correct paths (src/lib/source.ts and
src/lib/layout.shared.tsx); locate the paragraph listing these files in
README.md and replace the two occurrences so the documented filenames match the
actual project structure.
In `@apps/www/src/app/`(home)/page.tsx:
- Line 33: The className string on the JSX element contains both
"transition-colors" and "transition" which is redundant; edit the className (the
JSX element with the long inline className containing "inline-flex ...
transition-colors transition duration-150") and remove the redundant
"transition" token, keeping "transition-colors duration-150" for the intended
behavior.
In `@apps/www/src/app/docs/`[[...slug]]/page.tsx:
- Around line 20-24: Update the placeholder values in the gitConfig object: set
gitConfig.user to "yamcodes" and gitConfig.repo to "bedstack" (leave branch as
"main"); locate the gitConfig declaration in
apps/www/src/app/docs/[[...slug]]/page.tsx and replace the current 'username'
and 'repo' strings accordingly.
- Line 37: Update the githubUrl template used for the page link: change the path
segment from "docs/content/docs/${page.path}" to
"apps/www/content/docs/${page.path}" in the githubUrl expression (the template
referenced by githubUrl and page.path). Also replace placeholder gitConfig
values ('username' and 'repo') with the actual repository owner and name in the
gitConfig object so githubUrl resolves correctly.
- Line 14: The file references the PageProps type in the Page component
signature but never imports it; add an import such as `import type { PageProps }
from 'next'` at the top of the file so the Page function signature (export
default async function Page(props: PageProps<'/docs/[[...slug]]'>)) and any
other uses of PageProps compile under strict TypeScript; ensure you use an
`import type` to avoid runtime import side effects.
In `@apps/www/src/app/global.css`:
- Around line 92-94: The selector "&::selection" at the root of the `@layer` base
is invalid because the parent selector (&) can only be used inside another rule;
replace it with a top-level ::selection rule (i.e. change "&::selection { `@apply`
bg-primary text-primary-foreground; }" to "::selection { `@apply` bg-primary
text-primary-foreground; }") so the browser/Tailwind will apply the selection
styles correctly and keep it inside the same `@layer` base block.
In `@apps/www/src/app/og/docs/`[...slug]/route.tsx:
- Around line 16-26: The OG image uses a hardcoded site name "My App" in the
ImageResponse JSX; update the DefaultImage prop site to the real project name
(e.g., "Bedstack") or derive it from your app config/env so branding is correct.
Locate the ImageResponse call that renders <DefaultImage title={page.data.title}
description={page.data.description} site="My App" /> and replace the literal
with the correct constant or config value (or a safe fallback) so
DefaultImage.site reflects the actual project name.
In `@apps/www/src/components/ai/page-actions.tsx`:
- Around line 36-49: The current clipboard-copy flow around
navigator.clipboard.write and ClipboardItem uses fetch(markdownUrl) but doesn't
handle fetch failures or non-OK responses, so errors bubble up and nothing is
cached or surfaced to the user; wrap the fetch logic in a try/catch, check
response.ok and throw a descriptive error for non-200 responses, only call
cache.set(markdownUrl, content) after successful read, and on error set the UI
failure state (e.g., call setLoading(false) and the component's existing
error/notification setter such as setCopyError or a toast) before rethrowing or
returning so users see the failure.
- Around line 85-90: The SSR fallback sets fullMarkdownUrl to the literal string
'loading' inside useMemo (items, fullMarkdownUrl, markdownUrl, q) which yields
an invalid query on server and then changes on hydration; fix by deferring URL
computation to the client: replace the inline typeof window check with a
client-only state (e.g., useState<string | null>) and populate it in useEffect
using new URL(markdownUrl, window.location.origin), then have useMemo build
items only when that state is non-null (or return a safe server placeholder that
matches client until hydrated) so the memoized q and items stay stable between
SSR and client render.
🧹 Nitpick comments (11)
apps/www-legacy/.gitignore (1)
1-3: Standard VitePress ignore patterns.Appropriate ignore rules for VitePress cache and build output.
Minor nit: there's a trailing space after "cache" on line 1.
apps/www/src/lib/layout.shared.tsx (1)
13-26: Consider consolidating responsive logo handling.Both
Imagecomponents use the same source and alt text, with only size differences. The duplicate alt text may cause screen readers to announce "Bedstack" twice.💡 Suggested improvement
Consider using CSS to handle the size difference on a single image, or mark the mobile image as decorative:
<Image src="/logo-mini.png" alt="Bedstack" width={28} height={28} - className="hidden md:block" + className="size-6 md:size-7" /> - <Image - src="/logo-mini.png" - alt="Bedstack" - width={24} - height={24} - className="md:hidden" - />apps/www/src/app/global.css (1)
30-31: Multiple!importantoverrides for fumadocs header height.The
--fd-header-height: 80px !importantis declared in both:root(lines 30-31) and again in the layout selectors (lines 110-111). Consider consolidating to avoid redundancy.Also applies to: 110-111
apps/www/src/app/(home)/page.tsx (1)
1-4: Unused imports and potentially unnecessary client directive.
ArrowUpRightandRocketare imported but never used. Additionally,'use client'may be unnecessary since this component doesn't use any client-side hooks, event handlers, or browser APIs.♻️ Proposed fix
-'use client'; - import { SiGithub as GitHub } from '@icons-pack/react-simple-icons'; -import { ArrowRight, ArrowUpRight, BookOpen, Rocket } from 'lucide-react'; +import { ArrowRight, BookOpen } from 'lucide-react'; import Image from 'next/image'; import Link from 'next/link'; import { Button } from '@/components/ui/button';Verify if
'use client'is needed for any child component or fumadocs integration requirement not visible in this file.apps/www/src/app/layout.tsx (1)
17-28: Consider adding title and description to metadata.The metadata currently only configures icons. Adding
titleanddescriptionwould improve SEO and social sharing.💡 Example enhancement
export const metadata: Metadata = { + title: { + template: '%s | Bedstack', + default: 'Bedstack', + }, + description: 'An opinionated, typesafe backend stack built with Bun, ElysiaJS, and Drizzle ORM.', icons: { icon: [ { url: '/favicon.ico', sizes: 'any' },apps/www/src/lib/source.ts (1)
21-27: Consider adding error handling forgetText.If
page.data.getText('processed')fails or returns undefined/null, the function will produce malformed markdown. This could happen with pages that don't have processed content.💡 Optional: Add defensive handling
export async function getLLMText(page: InferPageType<typeof source>) { - const processed = await page.data.getText('processed'); + const processed = await page.data.getText('processed') ?? ''; return `# ${page.data.title} ${processed}`; }apps/www/src/app/llms-full.txt/route.ts (1)
5-10: Add Content-Type header for consistency.The similar route at
llms.mdx/docs/[[...slug]]/route.tssetsContent-Type: text/markdown. This route should also set an appropriate Content-Type header for proper client handling.💡 Add Content-Type header
export async function GET() { const scan = source.getPages().map(getLLMText); const scanned = await Promise.all(scan); - return new Response(scanned.join('\n\n')); + return new Response(scanned.join('\n\n'), { + headers: { + 'Content-Type': 'text/plain; charset=utf-8', + }, + }); }apps/www/src/app/og/docs/[...slug]/route.tsx (1)
29-34: Thelangproperty may be unused in this route.The route pattern is
/og/docs/[...slug]without a[lang]segment, butgenerateStaticParamsreturns{ lang, slug }. Next.js will ignore thelangproperty since it doesn't match any dynamic segment in the route path. If localization isn't needed for OG images, consider removing the unused property.💡 Remove unused lang property
export function generateStaticParams() { - return source.getPages().map((page) => ({ - lang: page.locale, - slug: getPageImage(page).segments, - })); + return source.getPages().map((page) => ({ + slug: getPageImage(page).segments, + })); }apps/www/package.json (1)
9-12: Redundanttypecheckscript alongsidetypes:check.Both
types:check(line 9) andtypecheck(line 12) runtsc --noEmit, buttypes:checkalso runsfumadocs-mdxandnext typegenfirst. Consider removing the simplertypecheckscript or clarifying when each should be used.Suggested consolidation
"types:check": "fumadocs-mdx && next typegen && tsc --noEmit", "postinstall": "fumadocs-mdx", "clean": "rimraf node_modules", - "typecheck": "tsc --noEmit",apps/www/content/docs/index.mdx (1)
15-17: Consider adding a description to the GitHub card for consistency.The other Card components include descriptions, but the GitHub Repository card doesn't. This is a minor consistency nit.
Suggested addition
<Cards> - <Card title="GitHub Repository" href="https://github.com/yamcodes/bedstack" /> + <Card title="GitHub Repository" href="https://github.com/yamcodes/bedstack" description="View the source code and contribute" /> </Cards>apps/www/src/app/docs/[[...slug]]/page.tsx (1)
36-38: Remove or update the template comment.The comment "update it to match your repo" is leftover from template code. After updating the
gitConfigvalues, this comment should be removed.Proposed fix
<ViewOptions markdownUrl={`${page.url}.mdx`} - // update it to match your repo githubUrl={`https://github.com/${gitConfig.user}/${gitConfig.repo}/blob/${gitConfig.branch}/docs/content/docs/${page.path}`} />
…oss www and www-legacy apps
…refine homepage content presentation.
…ask, and remove an unused import from the docs page.
…r-radius variables and element styling.
…n in documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@package.json`:
- Line 12: The package.json "docs:build" npm script currently points at the
deprecated "www-legacy" app; update the script so it targets the active "www"
app (i.e., change the turbo filter from "www-legacy" to "www") or, if you need
to preserve the legacy build, add a new script "docs:build:legacy" that points
to "www-legacy" and keep "docs:build" targeting "www"; locate and update the
"docs:build" entry in package.json and ensure consistency with the existing
"docs" and "www" scripts.
🧹 Nitpick comments (2)
apps/www/src/components/ai/page-actions.tsx (2)
50-55: RedundantsetLoading(false)in catch block.The
finallyblock always executes, so thesetLoading(false)in thecatchblock is unnecessary.Suggested fix
} catch (err) { console.error(err); - setLoading(false); } finally { setLoading(false); }
238-250: Consider usingitem.titleas key instead ofitem.href.While
item.hrefworks as a unique key, if any external service URL changes format, it could cause unnecessary re-renders. Usingitem.titleis more stable since titles are unlikely to change.Suggested fix
- {items.map((item) => ( - <a - key={item.href} + {items.map((item) => ( + <a + key={item.title}
| "typecheck": "turbo run typecheck", | ||
| "docs": "turbo run dev --filter=www", | ||
| "docs:build": "turbo run build --filter=www", | ||
| "docs:build": "turbo run build --filter=www-legacy", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's see the package.json file to understand the full context
cat package.json | head -50Repository: yamcodes/bedstack
Length of output: 1528
🏁 Script executed:
# List the main directories to understand the structure
git ls-files | head -1
fd -t d "^(www|docs|www-legacy)$" --max-depth 2Repository: yamcodes/bedstack
Length of output: 107
🏁 Script executed:
# Check what's in the root directory
ls -la | grep -E "^d"Repository: yamcodes/bedstack
Length of output: 452
🏁 Script executed:
# Check for README files that might explain www vs www-legacy
fd "README|MIGRATION" -iRepository: yamcodes/bedstack
Length of output: 208
🏁 Script executed:
# Check the package.json in both apps to understand their purpose
echo "=== apps/www/package.json ===" && cat apps/www/package.json 2>/dev/null | head -30
echo -e "\n=== apps/www-legacy/package.json ===" && cat apps/www-legacy/package.json 2>/dev/null | head -30Repository: yamcodes/bedstack
Length of output: 1364
🏁 Script executed:
# Check the structure of both directories
echo "=== apps/www structure ===" && ls -la apps/www/
echo -e "\n=== apps/www-legacy structure ===" && ls -la apps/www-legacy/Repository: yamcodes/bedstack
Length of output: 1509
🏁 Script executed:
# Let's check the README files to understand the migration status
echo "=== Main README ===" && cat README.md | head -50
echo -e "\n=== apps/www README ===" && cat apps/www/README.md
echo -e "\n=== apps/www-legacy README ===" && cat apps/www-legacy/README.mdRepository: yamcodes/bedstack
Length of output: 4554
docs:build script targets the legacy VitePress site instead of the current Fumadocs site.
The docs and www scripts correctly target the active www app, but docs:build targets the deprecated www-legacy. This causes a mismatch where development uses the current docs but builds compile the archived version. Either update docs:build to target www or create a separate docs:build:legacy script.
🤖 Prompt for AI Agents
In `@package.json` at line 12, The package.json "docs:build" npm script currently
points at the deprecated "www-legacy" app; update the script so it targets the
active "www" app (i.e., change the turbo filter from "www-legacy" to "www") or,
if you need to preserve the legacy build, add a new script "docs:build:legacy"
that points to "www-legacy" and keep "docs:build" targeting "www"; locate and
update the "docs:build" entry in package.json and ensure consistency with the
existing "docs" and "www" scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@apps/www/src/app/global.css`:
- Around line 141-145: The rule targeting `#nd-nav` > div and `#nd-subnav` > div
uses background-color: hsl(var(--background) / 0.8) but --background is defined
as an oklch(...) value, so hsl(...) is invalid; fix by either removing the
background-color declaration (rely on the existing Tailwind utility
bg-fd-background/80) or replace it with a proper oklch-aware expression such as
color-mix(in oklch, var(--background) 80%, transparent) or a dedicated alpha
variable (e.g., use var(--background-alpha) with oklch(... / <alpha>)); update
the styling in the rule for `#nd-nav` > div and `#nd-subnav` > div accordingly.
🧹 Nitpick comments (1)
apps/www/src/app/global.css (1)
190-214: Consider using CSS custom properties for animation timing.The
zzzanimation utilities work correctly. For easier future adjustments, you could extract the duration and delays into CSS variables.♻️ Optional enhancement
+:root { + --zzz-duration: 3s; +} + .animate-zzz-1 { - animation: zzz 3s infinite; + animation: zzz var(--zzz-duration) infinite; } .animate-zzz-2 { - animation: zzz 3s infinite 1s; + animation: zzz var(--zzz-duration) infinite 1s; } .animate-zzz-3 { - animation: zzz 3s infinite 2s; + animation: zzz var(--zzz-duration) infinite 2s; }
| #nd-nav > div, | ||
| #nd-subnav > div { | ||
| @apply backdrop-blur-lg bg-fd-background/80; | ||
| background-color: hsl(var(--background) / 0.8) !important; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Color function mismatch: hsl() used with oklch variable.
The --background variable is defined as oklch(...) (lines 26, 35), but line 144 wraps it in hsl(). This will produce invalid CSS since hsl() cannot interpret an oklch value.
🐛 Proposed fix
`#nd-nav` > div,
`#nd-subnav` > div {
`@apply` backdrop-blur-lg bg-fd-background/80;
- background-color: hsl(var(--background) / 0.8) !important;
+ background-color: oklch(from var(--background) l c h / 0.8) !important;
}Alternatively, if oklch relative color syntax isn't supported by your target browsers, you could define a separate --background-alpha variable or use the Tailwind utility already applied (bg-fd-background/80) and remove the duplicate declaration.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #nd-nav > div, | |
| #nd-subnav > div { | |
| @apply backdrop-blur-lg bg-fd-background/80; | |
| background-color: hsl(var(--background) / 0.8) !important; | |
| } | |
| `#nd-nav` > div, | |
| `#nd-subnav` > div { | |
| `@apply` backdrop-blur-lg bg-fd-background/80; | |
| background-color: oklch(from var(--background) l c h / 0.8) !important; | |
| } |
🤖 Prompt for AI Agents
In `@apps/www/src/app/global.css` around lines 141 - 145, The rule targeting
`#nd-nav` > div and `#nd-subnav` > div uses background-color: hsl(var(--background)
/ 0.8) but --background is defined as an oklch(...) value, so hsl(...) is
invalid; fix by either removing the background-color declaration (rely on the
existing Tailwind utility bg-fd-background/80) or replace it with a proper
oklch-aware expression such as color-mix(in oklch, var(--background) 80%,
transparent) or a dedicated alpha variable (e.g., use var(--background-alpha)
with oklch(... / <alpha>)); update the styling in the rule for `#nd-nav` > div and
`#nd-subnav` > div accordingly.
…egen` Turbo task, integrating it into the `typecheck` process.
Description
Closes #212
PR Checklist
bun docsSummary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.